home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dcpp / sym.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  6KB  |  291 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  SYM.C
  9.  *
  10.  */
  11.  
  12. #include "defs.h"
  13.  
  14. Prototype int hash(ubyte *, short);
  15. Prototype Sym *FindSymbol(ubyte *, short);
  16. Prototype int UndefSymbol(ubyte *, short);
  17. Prototype void DefineOptSymbol(char *);
  18. Prototype Sym *DefineSimpleSymbol(ubyte *, ubyte *, short);
  19. Prototype Sym *DefineSymbol(ubyte *, short, short, short, char **, short *, ubyte *, short, short, long);
  20.  
  21. Prototype void DumpPrecompSymbols(FILE *);
  22. Prototype void DefinePrecompSymbol(Sym *);
  23.  
  24. Prototype long SymGroup;
  25.  
  26. static Sym *SymHash[HSIZE];
  27. static Sym *SymCache;
  28.  
  29. long    SymGroup;
  30.  
  31. #ifdef NO_ASM
  32.  
  33. int
  34. hash(ubyte *ptr, short len)
  35. {
  36.     long hv = 0x1234FCD1;
  37.  
  38.     while (len) {
  39.     hv = (hv >> 23) ^ (hv << 5) ^ *ptr;
  40.     ++ptr;
  41.     --len;
  42.     }
  43.     return(hv & HMASK);
  44. }
  45.  
  46. #endif
  47.  
  48. Sym *
  49. FindSymbol(ubyte *name, short len)
  50. {
  51.     Sym *sym;
  52.     short hv = hash(name, len);
  53.  
  54.     for (sym = SymHash[hv & HMASK]; sym; sym = sym->Next) {
  55.     if (sym->Hv == hv && sym->SymLen == len && cmpmem(name, sym->SymName, len) == 0) {
  56.         if ((sym->Type & SF_SPECIAL) || (sym->Type & SF_RECURSE) == 0) {
  57.         if (sym->Type & SF_SPECIAL)
  58.             ModifySymbolText(sym, sym->Type);
  59.         break;
  60.         }
  61.     }
  62.     }
  63.     return(sym);
  64. }
  65.  
  66. int
  67. UndefSymbol(ubyte *name, short len)
  68. {
  69.     Sym **psym;
  70.     Sym *sym;
  71.     short hv = hash(name, len);
  72.  
  73.     for (psym = &SymHash[hv & HMASK]; (sym = *psym) != NULL; psym = &sym->Next) {
  74.     if (sym->Hv == hv && sym->SymLen == len && cmpmem(name, sym->SymName, len) == 0)
  75.         break;
  76.     }
  77.     if (sym == NULL)
  78.     return(0);
  79.     *psym = sym->Next;
  80.     sym->Next = SymCache;
  81.     SymCache = sym;
  82.     return(1);
  83. }
  84.  
  85. /*
  86.  *  handle single level define
  87.  */
  88.  
  89. void
  90. DefineOptSymbol(str)
  91. char *str;
  92. {
  93.     char *ptr;
  94.  
  95.     for (ptr = str; *ptr && *ptr != '='; ++ptr);
  96.     if (*ptr == '=') {
  97.     *ptr = ' ';
  98.     ++ptr;
  99.     ptr += strlen(ptr);
  100.     }
  101.     do_define(str, ptr - str, NULL);
  102. #ifdef NOTDEF
  103.     DefineSimpleSymbol(str, ptr, 0);
  104. #endif
  105. }
  106.  
  107. Sym *
  108. DefineSimpleSymbol(ubyte *symName, ubyte *symText, short symType)
  109. {
  110.     return(DefineSymbol(symName, strlen(symName), symType, -1, NULL, NULL, symText, 0, 0, strlen(symText)));
  111. }
  112.  
  113. Sym *
  114. DefineSymbol(
  115.     ubyte *name,
  116.     short len,
  117.     short type,
  118.     short numArgs,
  119.     char **args,
  120.     short *lens,
  121.     ubyte *text,
  122.     short allocName,
  123.     short allocText,
  124.     long textSize
  125. ) {
  126.     short hv = hash(name, len);
  127.     Sym **psym = &SymHash[hv & HMASK];
  128.     Sym *sym;
  129.  
  130.     if ((sym = SymCache) != NULL) {
  131.     SymCache = sym->Next;        /*    note, fields not zerod    */
  132.     } else {
  133.     sym = zalloc(sizeof(Sym));
  134.     }
  135.     sym->Next = *psym;
  136.     *psym = sym;
  137.  
  138.     if (allocName)
  139.     name = AllocCopy(name, len);
  140.     sym->SymName = name;
  141.     sym->SymLen  = len;
  142.     sym->Type     = type;
  143.     sym->NumArgs = numArgs;
  144.     sym->Hv     = hv;
  145.  
  146.     if (numArgs > 0) {
  147.     short i;
  148.  
  149.     sym->Args    = AllocCopy(args, numArgs * sizeof(char *));
  150.     sym->ArgsLen = AllocCopy(lens, numArgs * sizeof(short));
  151.     for (i = 0; i < numArgs; ++i)
  152.         sym->Args[i] = AllocCopy(args[i], lens[i]);
  153.     } else {
  154.     sym->Args      = NULL;
  155.     sym->ArgsLen   = NULL;
  156.     }
  157.     if (allocText)
  158.     text = AllocCopy(text, textSize);
  159.     sym->Text     = text;
  160.     sym->TextLen = textSize;
  161.     sym->SymGroup = SymGroup;
  162.  
  163.     return(sym);
  164. }
  165.  
  166. /*
  167.  *  Precompiled header file routines
  168.  */
  169.  
  170. void
  171. DefinePrecompSymbol(sym)
  172. Sym *sym;
  173. {
  174.     Sym **psym;
  175.  
  176.     /*
  177.      *    adjust pointers
  178.      */
  179.  
  180.     sym->SymName = (long)sym->SymName + (char *)sym;
  181.     if (sym->Args) {
  182.     int i;
  183.  
  184.     sym->Args = (ubyte **)((long)sym->Args + (char *)sym);
  185.     sym->ArgsLen = (short *)((long)sym->ArgsLen + (char *)sym);
  186.     for (i = 0; i < sym->NumArgs; ++i) {
  187.         sym->Args[i] = (long)sym->Args[i] + (char *)sym;
  188.     }
  189.     }
  190.     if (sym->Text)
  191.     sym->Text = (long)sym->Text + (char *)sym;
  192.  
  193.     /*
  194.      *    enter into hash table
  195.      */
  196.  
  197.     psym = &SymHash[sym->Hv & HMASK];
  198.     sym->Next = *psym;
  199.     *psym = sym;
  200. }
  201.  
  202. /*
  203.  *  dump symbols in current SymGroup
  204.  */
  205.  
  206. void
  207. DumpPrecompSymbols(fo)
  208. FILE *fo;
  209. {
  210.     long i;
  211.     Sym **psym;
  212.  
  213.     for (i = 0, psym = SymHash; i < HSIZE; ++i, ++psym) {
  214.     Sym *sym;
  215.  
  216.     for (sym = *psym; sym; sym = sym->Next) {
  217.         if (sym->SymGroup == SymGroup) {
  218.         long bytes = sizeof(Sym);
  219.         Sym xsym = *sym;
  220.  
  221.         /*
  222.          *  dump symbol
  223.          */
  224.  
  225.         xsym.SymName = (char *)bytes;
  226.         bytes += sym->SymLen;
  227.  
  228.         xsym.Text = (char *)bytes;
  229.         bytes += sym->TextLen;
  230.  
  231.         bytes = (bytes + 3) & ~3;   /*    LW-ALIGN    */
  232.  
  233.         if (sym->Args) {
  234.             int i;
  235.  
  236.             xsym.Args = (ubyte **)bytes;
  237.             bytes += sym->NumArgs * sizeof(char *);
  238.  
  239.             xsym.ArgsLen = (short *)bytes;
  240.             bytes += sym->NumArgs * sizeof(sym->ArgsLen[0]);
  241.  
  242.             for (i = 0; i < sym->NumArgs; ++i)
  243.             bytes += sym->ArgsLen[i];
  244.         }
  245.  
  246.         bytes = (bytes + 3) & ~3;   /*    LW-ALIGN    */
  247.  
  248.         fwrite(&bytes, sizeof(long), 1, fo);
  249.  
  250.         bytes = sizeof(Sym) + sym->SymLen + sym->TextLen;
  251.         fwrite(&xsym, sizeof(Sym), 1, fo);
  252.         fwrite(sym->SymName, sym->SymLen, 1, fo);
  253.         fwrite(sym->Text, sym->TextLen, 1, fo);
  254.  
  255.         while (bytes & 3) {
  256.             putc(0, fo);
  257.             ++bytes;
  258.         }
  259.  
  260.         if (sym->Args) {
  261.             int i;
  262.  
  263.             bytes += sym->NumArgs * sizeof(char *);
  264.             bytes += sym->NumArgs * sizeof(sym->ArgsLen[0]);
  265.  
  266.             for (i = 0; i < sym->NumArgs; ++i) {
  267.             fwrite(&bytes, sizeof(long), 1, fo);
  268.             bytes += sym->ArgsLen[i];
  269.             }
  270.             fwrite(sym->ArgsLen, sizeof(*sym->ArgsLen), sym->NumArgs, fo);
  271.  
  272.             /*
  273.              *    write argument text
  274.              */
  275.  
  276.             for (i = 0; i < sym->NumArgs; ++i)
  277.             fwrite(sym->Args[i], 1, sym->ArgsLen[i], fo);
  278.         }
  279.  
  280.         while (bytes & 3) {
  281.             putc(0, fo);
  282.             ++bytes;
  283.         }
  284.  
  285.         fwrite(&bytes, sizeof(long), 1, fo);
  286.         }
  287.     }
  288.     }
  289. }
  290.  
  291.